home *** CD-ROM | disk | FTP | other *** search
/ Best of Shareware / Best of PC Windows Shareware 1.0 - Wayzata Technology (7111) (1993).iso / mac / ZIPPED / DOS / GRAPHICS / RAYSH386.ZIP / SRC / TEXTURE.C < prev    next >
C/C++ Source or Header  |  1991-07-18  |  5KB  |  213 lines

  1. /*
  2.  * texture.c
  3.  *
  4.  * Copyright (C) 1989, 1991, Craig E. Kolb
  5.  * All rights reserved.
  6.  *
  7.  * This software may be freely copied, modified, and redistributed
  8.  * provided that this copyright notice is preserved on all copies.
  9.  *
  10.  * You may not distribute this software, in whole or in part, as part of
  11.  * any commercial product without the express consent of the authors.
  12.  *
  13.  * There is no warranty or other guarantee of fitness of this software
  14.  * for any purpose.  It is provided solely "as is".
  15.  *
  16.  * $Id: texture.c,v 4.0 91/07/17 14:44:11 kolb Exp Locker: kolb $
  17.  *
  18.  * $Log:    texture.c,v $
  19.  * Revision 4.0  91/07/17  14:44:11  kolb
  20.  * Initial version.
  21.  * 
  22.  */
  23. #include "texture.h"
  24.  
  25. /*
  26.  * Transformation structures used to map from texture space to
  27.  * model/primitive/world space.
  28.  */
  29. Trans prim2model, model2text, prim2text, world2text;
  30.  
  31. #define ApplyMapping(m,o,p,n,c,u,v)    (*m->method)(m, o, p, n, c, u, v)
  32.  
  33. Texture *
  34. TextCreate(data, meth)
  35. TextRef data;
  36. void (*meth)();
  37. {
  38.     Texture *res;
  39.  
  40.     res = (Texture *)share_calloc(1, sizeof(Texture));
  41.     res->data = data;
  42.     res->method = meth;
  43.     res->trans = (Trans *)NULL; 
  44.     res->next = (Texture *)NULL;
  45.     res->animtrans = FALSE;
  46.     return res;
  47. }
  48.  
  49. /*
  50.  * Apply appropriate textures to a surface.
  51.  */
  52. void
  53. TextApply(tlist, prim, ray, pos, norm, gnorm, surf, p2model, world2model)
  54. Texture *tlist;                /* Textures */
  55. Geom *prim;
  56. Ray *ray;
  57. Vector *pos, *norm, *gnorm;        /* pos, shading norm, geo. norm */
  58. Surface *surf;
  59. Trans *p2model, *world2model;
  60. {
  61.     Vector ptmp;
  62.     Texture *ttmp;
  63.  
  64.     prim2model = *p2model;
  65.     /*
  66.      * Walk down texture list, applying each in turn.
  67.      */
  68.     for (ttmp = tlist; ttmp; ttmp = ttmp->next) {
  69.         /*
  70.          * Make copies of pos & ray to pass to the texturing function.
  71.          */
  72.         ptmp = *pos;
  73.         if (ttmp->trans) {
  74.             /*
  75.              * 'take' the inverse of ttmp->trans, since
  76.              * transforming a texture means applying the
  77.              * inverse of the transformation
  78.              * to the point of intersection, etc.
  79.              */
  80.             if (ttmp->animtrans) {
  81.                 /*
  82.                  * Resolve animated associations.
  83.                  * We currently do not store a time
  84.                  * for the texture, so we can't know if
  85.                  * we're already resolved for the current
  86.                  * ray->time.
  87.                  */
  88.                 TransResolveAssoc(ttmp->trans);
  89.                 TransComposeList(ttmp->trans, &model2text);
  90.                 TransInvert(&model2text, &model2text);
  91.             } else
  92.                 TransInvert(ttmp->trans, &model2text);
  93.             /*
  94.              * We compose ttmp->trans, which maps from model to
  95.              * texture space, with prim2model and world2model
  96.              * to get prim2text and world2text.
  97.              */
  98.             TransCompose(&model2text, &prim2model, &prim2text);
  99.             TransCompose(&model2text, world2model, &world2text);
  100.             /*
  101.              * Transform intersection point to texture space.
  102.              * Ray and normal are passed in model space.
  103.              */
  104.             ModelPointToText(&ptmp);
  105.         } else {
  106.             /*
  107.               * By default, texture and model space are identical.
  108.               */
  109.             TransInit(&model2text);
  110.             TransCopy(&prim2model, &prim2text);
  111.             TransCopy(world2model, &world2text);
  112.         }
  113.  
  114.         /*
  115.          * Call texture function.
  116.          */
  117.         (*ttmp->method) (ttmp->data,prim,ray,&ptmp,norm,gnorm,surf);
  118.     }
  119. }
  120.  
  121. /*
  122.  * Compute UV at 'pos' on given primitive.
  123.  */
  124. TextToUV(mapping, prim, pos, norm, u, v, dpdu, dpdv)
  125. Mapping *mapping;
  126. Geom *prim;
  127. Vector *pos, *norm, *dpdu, *dpdv;
  128. Float *u, *v;
  129. {
  130.     Vec2d uv;
  131.     Vector ptmp;
  132.     RSMatrix t;
  133.  
  134.     ptmp = *pos;
  135.  
  136.     if (mapping->flags & PRIMSPACE) {
  137.         /*
  138.           * Convert point and normal to primitive space.
  139.           */
  140.         TextPointToPrim(&ptmp);
  141.     } else {
  142.         /*
  143.          * Convert point and normal to object space.
  144.          */
  145.         TextPointToModel(&ptmp);
  146.     }
  147.  
  148.     ApplyMapping(mapping, prim, &ptmp, norm, &uv, dpdu, dpdv);
  149.  
  150.     /*
  151.      * Transform UV by model2text.  We set X = u and Y = v,
  152.      * while Z = 0.
  153.      * Although the UV coordinates may be in prim space,
  154.      * we treat them as if they are model-space coords.
  155.      * This is due to the fact that we want the texture
  156.      * to be applied in model space.
  157.      */
  158.     ptmp.x = uv.u;
  159.     ptmp.y = uv.v;
  160.     ptmp.z = 0.;
  161.     PointTransform(&ptmp, &model2text.trans);
  162.     *u = ptmp.x;
  163.     *v = ptmp.y;
  164.     if (dpdu == (Vector *)NULL || dpdv == (Vector *)NULL)
  165.         return;
  166.     /*
  167.      * Here's the ugly part.
  168.      * Build initial UVN-->XYZ matrix...
  169.      */
  170.     ArbitraryMatrix(dpdu->x, dpdu->y, dpdu->z,
  171.              dpdv->x, dpdv->y, dpdv->z,
  172.              norm->x, norm->y, norm->z, 0., 0., 0., &t);
  173.     /*
  174.      * ...transform to model space...
  175.      */
  176.     MatrixMult(&t, &prim2model.trans, &t);
  177.     /*
  178.      * ... apply model2text in UVN space.
  179.      */
  180.     MatrixMult(&model2text.itrans, &t, &t);
  181.     dpdu->x = t.matrix[0][0];
  182.     dpdu->y = t.matrix[0][1];
  183.     dpdu->z = t.matrix[0][2];
  184.     dpdv->x = t.matrix[1][0];
  185.     dpdv->y = t.matrix[1][1];
  186.     dpdv->z = t.matrix[1][2];
  187.     (void)VecNormalize(dpdu);
  188.     (void)VecNormalize(dpdv);
  189. }
  190.  
  191. /*
  192.  * Append 'text' to the given linked list of textures.
  193.  * Note that 'text' may be a list, too.
  194.  */
  195. Texture *
  196. TextAppend(text, list)
  197. Texture *text, *list;
  198. {
  199.     Texture *tp;
  200.  
  201.     if (list) {
  202.         /*
  203.          * Walk to the end of the list
  204.          */
  205.         for (tp = list;tp->next ;tp = tp->next)
  206.                 ;
  207.         tp->next = text;
  208.         return list;
  209.     }
  210.     /* else */
  211.     return text;
  212. }
  213.